package deng.camel.examples;

import java.util.Properties;
import java.util.concurrent.CountDownLatch;

import javax.jms.ConnectionFactory;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.jboss.JBossPackageScanClassResolver;
import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.util.jndi.JndiContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import deng.camel.beans.processors.ExchangeLogger;

public class JBossQueueDemo extends RouteBuilder {
	
	private static Log logger = LogFactory.getLog(JBossQueueDemo.class);
	
	public static void main(String[] args) {
		new JBossQueueDemo().start();
	}
	
	private CountDownLatch latch = new CountDownLatch(1);
	private DefaultCamelContext camelContext;
	private JndiContext beanRegistry;
	private Processor countDownLatchProcessor;
		
	private class CountDownLatchProcessor implements Processor {
		@Override
		public void process(Exchange exchange) throws Exception {
			if (!Boolean.valueOf((String)exchange.getIn().getHeader("skipCountDownLatch"))) {
				logger.trace("Count down latch");
				latch.countDown();
			}
		}				
	}
	
	public void start() {
		try {
			countDownLatchProcessor = new CountDownLatchProcessor();
			beanRegistry = new JndiContext();
			camelContext = new DefaultCamelContext(beanRegistry);
			PackageScanClassResolver packageScanClassResolver = new JBossPackageScanClassResolver();
			camelContext.setPackageScanClassResolver(packageScanClassResolver );
			camelContext.addRoutes(this);
			beforeCamelStart();
			camelContext.start();
			afterCamelStart();
			latch.await();
			camelContext.stop();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}		
	}

	private void beforeCamelStart() {
		try {
			beanRegistry.bind("exchangeLogger", new ExchangeLogger());
			beanRegistry.bind("dataGenerator", new DataGenerator());
		} catch (NamingException e) {
			throw new RuntimeException(e);
		}
	}

	private void afterCamelStart() {
		ProducerTemplate producer = camelContext.createProducerTemplate();
		producer.sendBody("direct:startRoute", "Hello");
	}

	@Override
	public void configure() throws Exception {
		Properties props = new Properties();
		props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
		props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
		props.setProperty(Context.PROVIDER_URL, "localhost:1099");
		Context context = new InitialContext(props);
		ConnectionFactory connectionFactory = (ConnectionFactory)context.lookup("ConnectionFactory");
		//sendStandAloneMsgTest(connectionFactory);
		JmsComponent jbossMessaging = JmsComponent.jmsComponent(connectionFactory);
		getContext().addComponent("jbossMessaging", jbossMessaging);
		
//		from("direct:startRoute")
//		.to("bean:dataGenerator")
//		.to("bean:exchangeLogger")
//		.to("jbossMessaging:queue:ExampleQueue2")
//		.process(countDownLatchProcessor);
			
		from("direct:startRoute")
			.to("bean:dataGenerator")
			.to("bean:exchangeLogger")
			.to("jbossMessaging:queue:ExampleQueue2");
		
		from("jbossMessaging:queue:ExampleQueue2")
			.to("bean:exchangeLogger")
			.process(countDownLatchProcessor);
	}
	
//	private void sendStandAloneMsgTest(ConnectionFactory connectionFactory) {
//		JmsTemplate jt = new JmsTemplate(connectionFactory);
//		
//		jt.send("ExampleQueue2", new MessageCreator() {
//
//			@Override
//			public Message createMessage(Session session) throws JMSException {
//				Message msg = session.createMessage();
//				logger.info("Sending " + msg);
//				return msg;
//			}
//			
//		});
//	}

	public static class DataGenerator {
		public String generateSamples() {
			return "<sample/>";
		}
	}

}

